package cn.com.vs.api;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.ws.rs.DefaultValue;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;

import cn.com.vs.Configurator;
import cn.com.vs.model.GeneralJSONResult;
import cn.com.vs.service.StoreService;
import cn.com.vs.service.WeatherService;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.net.MediaType;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import com.mashape.unirest.request.HttpRequestWithBody;

@Path("/pub/") 
public class PublicApi {

	private static Map<String,String> mediaType = new HashMap<String,String>();
	static {
		mediaType.put("png", MediaType.PNG.toString() );
		mediaType.put("pdf", MediaType.PDF.toString() );
		mediaType.put("jpg", MediaType.JPEG.toString() );
		mediaType.put("jpeg", MediaType.JPEG.toString() );
		mediaType.put("gif", MediaType.GIF.toString() );
		mediaType.put("bmp", MediaType.BMP.toString() );
		mediaType.put("xls", MediaType.MICROSOFT_EXCEL.toString() );
		mediaType.put("word", MediaType.MICROSOFT_WORD.toString() );
		mediaType.put("json", MediaType.JSON_UTF_8.toString() );
		mediaType.put("xml", MediaType.XML_UTF_8.toString() );
		mediaType.put("*", MediaType.ANY_APPLICATION_TYPE.toString() );
		mediaType.put("javascript", MediaType.JAVASCRIPT_UTF_8.toString() );
	}

	protected static Cache<String, String> authCache = CacheBuilder.newBuilder().expireAfterWrite(120, TimeUnit.SECONDS).build();

	
	public static String createUrl(String funAndOperate)
	{
		// 时间戳
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");

		String timestamp = sdf.format(new Date());

		String accountSid = Configurator.getInstance().getString("authcode_sid");
		if( StringUtils.isEmpty(accountSid) )
			return null;

		String key = Configurator.getInstance().getString("authcode_token");
		if( StringUtils.isEmpty(key) )
			return null;

		String url = Configurator.getInstance().getString("authcode_url");
		if( StringUtils.isEmpty(url) )
			return null;
		String version = Configurator.getInstance().getString("authcode_version");
		if( StringUtils.isEmpty(version) )
			return null;
		String appid = Configurator.getInstance().getString("authcode_appid");
		if( StringUtils.isEmpty(appid) )
			return null;
		// 签名
		String sig = DigestUtils.md5Hex( accountSid + key + timestamp);

		return url+"/"+version+ "/accounts/" + accountSid + "/" + funAndOperate + "sig=" + sig + "&timestamp=" + timestamp;
	}
	
	@Path("/res/{token}")
	@GET
	public Response resource( @PathParam("token") String token )
	{
		if( StringUtils.isEmpty(token) ){
			return Response.status(HttpStatus.SC_NOT_FOUND).entity(Entity.text("token missing")).build();
		}
		JSONObject resourceData = StoreService.getInstance().getData("_pub_",token);
		if( resourceData == null ){
			return Response.status(HttpStatus.SC_NOT_FOUND).entity(Entity.text("token resource not exist")).build();
		}else{
			String type = resourceData.getString("extType");
			String typeName = mediaType.get(type.toLowerCase());
			if( typeName == null ){
				return Response.status(HttpStatus.SC_NOT_FOUND).entity(Entity.text("token resource media type not support")).build();
			}
			try 
			{
				long len = resourceData.getInteger("size");
				if( len == 0 ){
					return Response.status(HttpStatus.SC_NO_CONTENT).build();
				}
				String base64Data = resourceData.getString("data");
				Response response = Response.ok()
						.header(HttpHeaders.CONTENT_TYPE, typeName)
						.entity(Base64.decodeBase64(base64Data))
						.build();
				return response;
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return Response.status(HttpStatus.SC_NOT_FOUND).build();
	}

	@GET
	@Path("/weather/{city}")
	@Produces(javax.ws.rs.core.MediaType.APPLICATION_JSON)
	public String weather( @PathParam("city") String city )
	{

		if( StringUtils.isEmpty(city) ){
			JSONObject ret = new JSONObject();
			ret.put("ok", false);
			ret.put("message", "城市或地区名不能为空");
			return ret.toJSONString();
		}
		return WeatherService.getInstance().queryWeather(city).toJSONString();
	}

	/**
	 * 发送注册验证码
	 * 2016-01-25
	 */
	@POST
	@Path("/sendAuthCode/{phone}")
	@Produces(javax.ws.rs.core.MediaType.APPLICATION_JSON)
	public String sendAuthCode(
			@PathParam("phone") String phone,
			@DefaultValue("sms") @FormParam("type") String authType){
		GeneralJSONResult st = new GeneralJSONResult();
		if( authCache.getIfPresent(phone) != null ){
			st.setOk(false);
			st.setMessage("请求过快，请稍后再试");
		}else{
			int code = (int) ((Math.random()*1000000)%100000);
			String strCode = String.format("%05d", code);
			JSONObject body = new JSONObject();
			
			
			
			JSONObject templateContent = new JSONObject();
			templateContent.put("appId", Configurator.getInstance().getString("authcode_appid"));
			String bussinessUrl = "SMS/templateSMS?";
			if( authType != null && authType.compareTo("voice")==0){
				bussinessUrl = "call/voiceCode?";
				templateContent.put("verifyCode", strCode);
				templateContent.put("called", phone);
				templateContent.put("playTimes", "3");
				body.put("voiceCode", templateContent);
			}else{
				String templateID = Configurator.getInstance().getString("authcode_templateid");
				templateContent.put("templateId", templateID);
				templateContent.put("to", phone);
				templateContent.put("param", strCode);
				body.put("templateSMS", templateContent);
			}

			String url = createUrl(bussinessUrl );
			if( url == null ){
				st.setOk(false);
				st.setMessage("短信验证参数不完整");
				return st.toString();
			}


			HttpRequestWithBody request = Unirest.post(url);
			request.header("Content-Type", "application/json;charset=utf-8");
			request.header("Accept", "application/json");

			request.body(body.toJSONString());
			try {
				HttpResponse<String> res = request.asString();
				if( res.getStatus() != 200 ){
					st.setOk(false);
					st.setMessage("验证码服务访问失败,状态码:"+res.getStatus());
				}else{
					JSONObject resp = JSON.parseObject(res.getBody());
					String respCode = resp.getJSONObject("result").getString("respCode");
					if( "00000".compareTo(respCode)  == 0){
						authCache.put(phone, strCode);
					}else{
						authCache.put(phone, strCode);
						st.setOk(false);
						st.setMessage("验证码服务失败:"+respCode+" 发送["+phone+"]验证码:"+strCode);
						return st.toString();
					}
					JSONObject result = resp.getJSONObject("result");
					result.remove("respCode");
					st.setOk(true);
					st.setData(result);
				}
			} catch (UnirestException e) {
				e.printStackTrace();
				st.setOk(false);
				st.setMessage("验证码服务访问异常:"+e.getMessage());
			}

		}
		return st.toString();
	}
}
